package com.yuntsg.nnsfcp.service.front.ut;


import com.yuntsg.nnsfcp.common.utils.StringUtil;
import com.yuntsg.nnsfcp.util.httpclient.HttpClientConfig;
import com.yuntsg.nnsfcp.util.httpclient.HttpClientUtil;
import com.yuntsg.nnsfcp.util.httpclient.LoadInfoShangjiao;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.CookieStore;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.http.HttpHeaders;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 自定义简单的 HTTP Clint 工具类
 *
 * @author ：ljx
 * @date ：Created in 2019/7/28
 */
public class MyHttpGet {

    /**
     * 发送一个get请求, 针对与知网,抓复合因子的
     *
     * @param cookieStore cookie
     * @param url         请求地址
     * @param referer     上一个页面
     * @return
     */
    public static String getHtmlCnki(CookieStore cookieStore, String url, String referer) {
        System.out.println("httpclient里面的地址" + url);
        String html = "";
        for (int i = 1; i <= 3; i++) {
            cookieStore = new BasicCookieStore();
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .build();
            HttpGet httpget = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse responce = null;
            try {
                httpget = new HttpGet(url);
                httpget.addHeader(HttpHeaders.REFERER, referer);

                //设置超时
                RequestConfig requestConfig = buildRequestConfigure(false);
                httpget.setConfig(requestConfig);

                //uuid cnkiUserKey 每次都是新的用户
                UUID uuid = UUID.randomUUID();
                System.out.println(uuid.toString());
                //用于生成id地址. 动态访问, 避免response响应回验证码
                int i1 = (int) (Math.random() * 255 + 3);
                int i2 = (int) (Math.random() * 255 + 3);
                int i3 = (int) (Math.random() * 255 + 3);
                int i4 = (int) (Math.random() * 255 + 3);
                System.out.println(i1 + "." + i2 + "." + i3 + "." + i4);
                //拼接cookie地址, 注意删除(不要拼接) ASP.NET_SessionId.
                httpget.addHeader("Cookie", "Ecp_ClientId=5190728131501173552; SID_navi=120161; cnkiUserKey=" + uuid.toString() + "; Ecp_IpLoginFail=190730" + i1 + "." + i2 + "." + i3 + "." + i4 + "; _pk_ses=*");
                //写死了, 知网首页
                httpget.addHeader(HttpHeaders.HOST, "navi.cnki.net");
                httpget.addHeader(HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.142 Safari/537.36");
                httpget.addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
                httpget.addHeader("X-Requested-With", "XMLHttpRequest");
                // 得到responce对象
                responce = httpClient.execute(httpget);
                // 返回码
                int resStatu = responce.getStatusLine().getStatusCode();
                System.out.println("状态码" + resStatu);
                System.out.println("httpclient耗时"
                        + (System.currentTimeMillis() - time1));
                // 200正常 其他就不对
                if (resStatu == HttpStatus.SC_OK) {
                    // 获得相应实体
                    HttpEntity entity = responce.getEntity();
                    if (entity != null) {
                        html = EntityUtils.toString(entity, "UTF-8");
                        if (!html.contains("请输入以下验证码")) {
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("查看异常的字符串" + e.toString());
                if (e.toString().contains("java.net.UnknownHostException")) {

                }
                if (e.toString().contains("connect time out")) {

                }
            } finally {
                if (httpClient != null) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (responce != null) {
                    try {
                        responce.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }

    /**
     * cnki的get方法 在线检索用的
     */
    public static String getHtmlCnkiBySearch(BasicCookieStore cookieStore, HttpClientConfig config) {
        System.out.println("当前的地址:" + config.getUrl());
        String html = null;
        for (int i = 1; i <= 3; i++) {
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .setDefaultCredentialsProvider(config.getCredsProvider())
                    .build();
            HttpGet httpget = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse response = null;
            try {
                httpget = new HttpGet(config.getUrl());
                httpget.setConfig(config.getRequestConfig());
                httpget.addHeader(org.apache.http.HttpHeaders.USER_AGENT, HttpClientConfig.USER_AGENT);

                //设置超时
                httpget.setConfig(buildRequestConfigure(false));

                if (!StringUtil.isEmpty(config.getRefer())) {
                    httpget.addHeader(org.apache.http.HttpHeaders.REFERER, config.getRefer());
                }
                if (!StringUtil.isEmpty(config.getHost())) {
                    httpget.addHeader(org.apache.http.HttpHeaders.HOST, config.getHost());
                }

                response = httpClient.execute(httpget);
                int resStatu = response.getStatusLine().getStatusCode();
                System.out.println("httpclient耗时" + (System.currentTimeMillis() - time1) + "--状态码" + resStatu);

                //个别页面有跳转操作, 原地址会返回404, 这种页面单独处理
                if (resStatu == HttpStatus.SC_NOT_FOUND) {
                    html = "404";
                    break;
                }
                if (resStatu == HttpStatus.SC_OK) {
                    html = HttpClientUtil.parsingHtml(response);
                    if (html != null) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (httpClient != null) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }

    /**
     * 发送一个post请求, 针对与知网
     *
     * @param cookieStore 存储cookie
     * @param map         参数map
     * @param config      请求头配置
     * @return
     */
    public static String postHtmlCnki(CookieStore cookieStore, Map<String, String> map, HttpClientConfig config) {
        System.out.println("httpclient里面的地址" + config.getUrl());
        String html = "";
        for (int i = 1; i <= 3; i++) {

            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .setDefaultCredentialsProvider(config.getCredsProvider())
                    .build();

            HttpPost httppost = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse responce = null;
            try {
                httppost = new HttpPost(config.getUrl());
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                if (map != null) {
                    for (Map.Entry<String, String> entry : map.entrySet()) {
                        nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
                    }
                }

                //设置超时
                httppost.setConfig(buildRequestConfigure(false));

                //uuid cnkiUserKey 每次都是新的用户
                UUID uuid = UUID.randomUUID();
                System.out.println(uuid.toString());
                //用于生成id地址. 动态访问, 避免response响应回验证码
                int i1 = (int) (Math.random() * 255 + 3);
                int i2 = (int) (Math.random() * 255 + 3);
                int i3 = (int) (Math.random() * 255 + 3);
                int i4 = (int) (Math.random() * 255 + 3);
                System.out.println(i1 + "." + i2 + "." + i3 + "." + i4);
                //拼接cookie地址, 注意删除(不要拼接) ASP.NET_SessionId.
                httppost.addHeader("Cookie", "Ecp_ClientId=5190728131501173552; SID_navi=120161; cnkiUserKey=" + uuid.toString() + "; Ecp_IpLoginFail=190730" + i1 + "." + i2 + "." + i3 + "." + i4 + "; _pk_ses=*");


                httppost.setEntity(new UrlEncodedFormEntity(nvps, "utf8"));
                httppost.setConfig(config.getRequestConfig());
                httppost.setHeader("Content-type", "application/x-www-form-urlencoded");

                httppost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:49.0) Gecko/20100101 Firefox/49.0");
                if (!StringUtils.isEmpty(config.getRefer())) {
                    httppost.addHeader(HttpHeaders.REFERER, config.getRefer());
                }
                if (!StringUtils.isEmpty(config.getHost())) {
                    httppost.addHeader(HttpHeaders.HOST, config.getHost());
                }

                responce = httpClient.execute(httppost);
                int resStatu = responce.getStatusLine().getStatusCode();
                System.out.println("httpclient耗时" + (System.currentTimeMillis() - time1) + "状态码" + resStatu);
                //获得相应实体
                if (resStatu == HttpStatus.SC_OK) {
                    html = HttpClientUtil.parsingHtml(responce);
                    if (html != null) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("查看异常的字符串" + e.toString());
                if (e.toString().contains("java.net.UnknownHostException")) {

                }
                if (e.toString().contains("connect time out")) {
                }
            } finally {
                if (httpClient != null) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (responce != null) {
                    try {
                        responce.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }

    /**
     * 原生的httpGet 请求
     *
     * @param cookieStore cookie
     * @param config      请求配置
     * @return
     */
    public static String getHtmlGeneral(BasicCookieStore cookieStore, HttpClientConfig config) {
        System.out.println("当前的地址:" + config.getUrl());
        String html = null;
        for (int i = 1; i <= 3; i++) {
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .setDefaultCredentialsProvider(config.getCredsProvider())
                    .build();

            HttpGet httpget = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse response = null;
            try {
                httpget = new HttpGet(config.getUrl());
                httpget.setConfig(config.getRequestConfig());
                httpget.addHeader(org.apache.http.HttpHeaders.USER_AGENT, HttpClientConfig.USER_AGENT);

                //设置超时
                httpget.setConfig(buildRequestConfigure(true));

                if (!StringUtil.isEmpty(config.getRefer())) {
                    httpget.addHeader(org.apache.http.HttpHeaders.REFERER, config.getRefer());
                }
                if (!StringUtil.isEmpty(config.getHost())) {
                    httpget.addHeader(org.apache.http.HttpHeaders.HOST, config.getHost());
                }
                response = httpClient.execute(httpget);
                int resStatu = response.getStatusLine().getStatusCode();
                System.out.println("httpclient耗时" + (System.currentTimeMillis() - time1) + "--状态码" + resStatu);
                if (resStatu == HttpStatus.SC_OK) {
                    html = HttpClientUtil.parsingHtml(response);
                    if (html != null) {
                        break;
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (httpClient != null) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (response != null) {
                    try {
                        response.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }

    /**
     * EI 在线检索 get请求
     *
     * @param cookieStore
     * @param url
     * @param referer
     * @return
     */
    public static String getHtmlByEi(CookieStore cookieStore, String url, String referer) {
        System.out.println("httpclient里面的地址" + url);
        String html = "";
        CredentialsProvider credsProvider = LoadInfoShangjiao.build();
        for (int i = 1; i <= 3; i++) {
            CloseableHttpClient httpClient = HttpClients.custom()
                    .setDefaultCookieStore(cookieStore)
                    .setDefaultCredentialsProvider(credsProvider)
                    .build();
            HttpGet httpget = null;
            long time1 = System.currentTimeMillis();
            CloseableHttpResponse responce = null;
            try {
                httpget = new HttpGet(url);
                //超时
                httpget.setConfig(buildRequestConfigure(true));
                httpget.addHeader(org.apache.http.HttpHeaders.USER_AGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36");
                httpget.addHeader(org.apache.http.HttpHeaders.REFERER, referer);
                responce = httpClient.execute(httpget);// 得到responce对象
                int resStatu = responce.getStatusLine().getStatusCode();// 返回码
                System.out.println("状态码" + resStatu);
                System.out.println("httpclient耗时" + (System.currentTimeMillis() - time1));
                if (resStatu == HttpStatus.SC_OK) {// 200正常 其他就不对
                    HttpEntity entity = responce.getEntity(); // 获得相应实体
                    if (entity != null) {
                        html = EntityUtils.toString(entity, "UTF-8").replace(
                                "&nbsp;", " ");
                        if (!html.contains("请输入以下验证码")) {
                            break;
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("查看异常的字符串" + e.toString());
                if (e.toString().contains("java.net.UnknownHostException")) {

                }
                if (e.toString().contains("connect time out")) {

                }
            } finally {
                if (httpClient != null) {
                    try {
                        httpClient.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if (responce != null) {
                    try {
                        responce.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                httpClient.getConnectionManager().shutdown();
            }
        }
        return html;
    }


    /**
     * 设置httpClent请求超时
     *
     * @param JumpFlag
     * @return
     */
    private static RequestConfig buildRequestConfigure(boolean JumpFlag) {
        return RequestConfig.custom()
                //没有链接,没有响应超时断开
                .setSocketTimeout(60000)
                //链接后没有响应数据, 超时断开
                .setConnectTimeout(60000)
                //.setProxy(new HttpHost(PROXY_STR,PORT_STR))
                //是否重定向
                //.setRedirectsEnabled(JumpFlag)
                .build();// 设置请求和传输超时时间
    }
}
